package com.jule.teenpatti.mail.network;

import com.jule.teenpatti.mail.network.protocol.ClientReq;
import com.jule.teenpatti.mail.network.protocol.reqs.*;
import com.jule.teenpatti.mail.service.holder.FunctionIdHolder;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

public class ClientPacketFactory {

    private static final ClientPacketHolder CLIENT_PACKET_HOLDER = new ClientPacketHolder();

    private static class SingletonHolder {
        protected static final ClientPacketFactory instance = new ClientPacketFactory();
    }

    public static final ClientPacketFactory getInstance() {
        return ClientPacketFactory.SingletonHolder.instance;
    }

    private ClientPacketFactory() {
        CLIENT_PACKET_HOLDER.addPacketPrototype(new DispacherPingReq_01(1));//网关心跳

        CLIENT_PACKET_HOLDER.addPacketPrototype(new JoloCommon_LoginReq_600001(600001));

        CLIENT_PACKET_HOLDER.addPacketPrototype(new JoloAuth_RedDotReq_600020(FunctionIdHolder.Mail_REQ_RedDots));

        CLIENT_PACKET_HOLDER.addPacketPrototype( new JoloAuth_MailListReq_600021(FunctionIdHolder.Mail_REQ_MailList));
        CLIENT_PACKET_HOLDER.addPacketPrototype(new JoloAuth_MailCheckReq_600022(FunctionIdHolder.Mail_REQ_MailCheck));
        CLIENT_PACKET_HOLDER.addPacketPrototype(new JoloAuth_MailAwardReq_600023(FunctionIdHolder.Mail_REQ_MailAward));
        CLIENT_PACKET_HOLDER.addPacketPrototype(new JoloAuth_MailDelReq_600024(FunctionIdHolder.Mail_REQ_MailDel));

    }

    public ClientReq getClientReq(int functionId, ChannelHandlerContext channelHandlerContext) {
//        logger.debug("getClientReq");
        return CLIENT_PACKET_HOLDER.getPacket(functionId, channelHandlerContext);
    }

    @Slf4j
    public static class ClientPacketHolder {

        private Map<Integer, ClientReq> packetsPrototypes = new HashMap<>();

        /**
         * @param req
         */
        public void addPacketPrototype(ClientReq req) {
            packetsPrototypes.put(req.getFunctionId(), req);
        }

        /**
         * @param functionId
         * @param channelHandlerContext
         * @return
         */
        private ClientReq getPacket(int functionId, ChannelHandlerContext channelHandlerContext) {
            ClientReq prototype = packetsPrototypes.get(functionId);

            if (prototype == null) {
                unknownPacket(functionId);
                return null;
            }

            ClientReq req = prototype.clone();
            req.setCtx(channelHandlerContext);

            return req;
        }

        /**
         * @param functionId
         */
        private void unknownPacket(int functionId) {
            log.warn(String.format("Unknown packet recived from client: %s", functionId));
        }
    }
}
